<?php

namespace App\Http\Services;

use App\Http\Model\Hint;
use App\Http\Model\RoomUser;
use App\Http\Model\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use ZEGO\ZegoErrorCodes;
use ZEGO\ZegoServerAssistant;

class ZegoServices extends CommonServices
{
    //权限位定义
    const PrivilegeKeyLogin   = 1; // 登录
    const PrivilegeKeyPublish = 2; // 推流

    //权限开关定义
    const PrivilegeEnable     = 1; // 开启
    const PrivilegeDisable    = 0; // 关闭

    protected $model_user;
    protected $roomService;
    protected $errorLog = 'error_zego';
    protected $log = 'zego';

    public function __construct()
    {
        $this->model_user = new User();
        $this->roomUser = new RoomUser();
    }

    //生成即构token
    public function getZegoToken($roomId, $userId=0){
        if(empty($userId)){
            $user = $this->model_user->get_current_user();
            if (empty($user)) {
                return null;
            }
            $userId = (string)$user['user_id'];
        }else{
            $userId = (string)$userId;
        }
        //配置
        $config = config('zego');
        $appId = (int)$config['appId'];
        $secret = $config['appCertificate'];

        $roomId = $roomId;
        $outTime = 24 * 3600;
        
        //生成token
        $rtcRoomPayLoad = [
            'room_id' => $roomId, //房间id；用于对接口的房间id进行强验证
            'privilege' => [     //权限位开关列表；用于对接口的操作权限进行强验证
                PrivilegeKeyLogin => PrivilegeEnable,
                PrivilegeKeyPublish => PrivilegeDisable,
            ],
            'stream_id_list' => [] //流列表；用于对接口的流id进行强验证；允许为空，如果为空，则不对流id验证
        ];
        
        $payload = json_encode($rtcRoomPayLoad);
        $token = ZegoServerAssistant::generateToken04($appId,$userId,$secret,$outTime,$payload);
        if( $token->code == ZegoErrorCodes::success ){
            return $token->token;
        }
        return null;
    }

    //断开即构链接
    public function kickoutUser($userId, $roomId){
        do{
            if(empty($userId)){
                break;
            }
            //踢出房间
            $url = 'https://rtc-api.zego.im/?Action=KickoutUser';
            $config = config('zego');
            $appId = (int)$config['appId'];    
            $secret = $config['appCertificate'];
            $time = time();
            $str = bin2hex(random_bytes(8));
            //秘钥签名
            $Signature = md5($appId.$str.$secret.$time);
            $param = [
                'RoomId' => $roomId,
                'UserId[]' => $userId,
                'CustomReason' => urlencode('用户断开网络链接'),
                'AppId' => $appId,
                'SignatureNonce' => $str,
                'SignatureVersion' => '2.0',
                'Timestamp' => $time,
                'Signature' => $Signature,
            ];
            $res = $this->curl_request($url,$param,'urlencoded','GET');
            //write_log($this->log,'INFO 踢出用户',['res'=>$res,'param' => $param]);
        }while(false);
        return true;
    }

    public function  curl_request($action, $params, $contentType = 'urlencoded', $httpMethod = 'POST', $httpHeader = [])
    {
        $ch = curl_init();
        if ($httpMethod == 'POST' && $contentType == 'urlencoded') {
            $httpHeader[] = 'Content-Type:application/x-www-form-urlencoded';
            curl_setopt($ch, CURLOPT_POSTFIELDS, build_query($params));
        }
        if ($httpMethod == 'POST' && $contentType == 'json') {
            $httpHeader[] = 'Content-Type:application/json';
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        }
        if ($httpMethod == 'POST' && $contentType == 'plain') {
            $httpHeader[] = 'Content-Type:text/plain';
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }
        if ($httpMethod == 'GET' && $contentType == 'urlencoded') {
            $action .= strpos($action, '?') === false ? '?' : '&';
            $action .= build_query($params);
        }
        curl_setopt($ch, CURLOPT_URL, $action);
        curl_setopt($ch, CURLOPT_POST, $httpMethod == 'POST');
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //处理http证书问题
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        // dd(curl_getinfo($ch));
        $ret = curl_exec($ch);
        if (false === $ret) {
            $ret = curl_errno($ch);
        }
        curl_close($ch);
        return $ret;
    }
}